package io.lkt.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

public class ChromeUtil {
    // 改成同步方法
    public static synchronized String getPageSource(String url) {
        // html 页面
        String pageSource = "";

        ChromeDriverService service = null;
        ChromeDriver driver = null;
        try {
            service = new ChromeDriverService.Builder()
                    .usingDriverExecutable(new File("/usr/bin/chromedriver"))
                    .usingAnyFreePort().build();

            //创建一个参数对象，用来控制chrome以无界面模式打开
            ChromeOptions options = new ChromeOptions();
            options.addArguments("--headless");
            options.addArguments("--disable-gpu");
            options.addArguments("--no-sandbox");

            service.start();
            driver = new ChromeDriver(service, options);
            driver.get(url);

            Thread.sleep(10000);// 等待

            pageSource = driver.getPageSource();
        } catch (Exception e) {

        } finally {
            if (driver != null) {
                driver.close();// 关闭浏览器当前 Tab 页
                driver.quit();// 退出浏览器
            }

            if (service != null) {
                service.stop();
            }
        }

        return pageSource;
    }

    /**
     * 解析动态 js 页面的视频链接
     * @param weiXinPageUrl 微信链接地址
     * @return html
     */
    public static List<String> parseVideo(String weiXinPageUrl) {
        final String videoElementPrefixName = "<video";// video 标签前缀
        final String iframeElementPrefixName = "<iframe";// iframe 标签前缀

        List<String> videoLinkList = new ArrayList<>();// 最终结果
        List<Map<String, Object>> videoSource = new ArrayList<>();// 主要用于视频排序

        try {
            String pageSource = getPageSource(weiXinPageUrl);

//            System.out.println("[pageSource] = " + pageSource);

            Document document = Jsoup.parse(pageSource);// 解析文本
            Element content = document.select("div#js_content").first();// 解析文本

            if (content != null) {
                // 第一步：解析 video 标签
                int videoOffset = 0;
                Elements videoElements = content.select("video");// video 标签
                if (!videoElements.isEmpty()) {
                    for (Element videoElement : videoElements) {
                        String src = videoElement.attr("src");// src 属性
                        if (StringUtils.isNotBlank(src)) {
                            int index = pageSource.indexOf(videoElementPrefixName, videoOffset);// video 元素的位置

                            Map<String, Object> videoOptions = new HashMap<>();
                            videoOptions.put("index", Integer.valueOf(index));
                            videoOptions.put("src", src.startsWith("//") ? "https:" + src : src);// 以 // 开头的链接，加上 https: 协议头

                            videoSource.add(videoOptions);

                            videoOffset = index + videoElementPrefixName.length();// 偏移量增加
                        }
                    }
                }

                // 第二步：解析 iframe 标签
                int iframeOffset = 0;
                Elements iframeElements = content.select("iframe");// iframe 标签
                if (!iframeElements.isEmpty()) {
                    for (Element iframeElement : iframeElements) {
                        String src = iframeElement.attr("src");// src 属性
                        if (StringUtils.isNotBlank(src)) {
                            int index = pageSource.indexOf(iframeElementPrefixName, iframeOffset);// iframe 元素的位置

                            Map<String, Object> iframeOptions = new HashMap<>();
                            iframeOptions.put("index", Integer.valueOf(index));
                            iframeOptions.put("src", src.startsWith("//") ? "https:" + src : src);// 以 // 开头的链接，加上 https: 协议头

                            videoSource.add(iframeOptions);

                            iframeOffset = index + iframeElementPrefixName.length();// 偏移量增加
                        }
                    }
                }

                // 第三步：对结果集排序
                if (!CollectionUtils.isEmpty(videoSource) && videoSource.size() > 0) {
                    videoSource.stream().sorted(Comparator.comparing(ChromeUtil::getIndexValueInMap)).collect(Collectors.toList())
                            .forEach(info -> {
                                videoLinkList.add(info.get("src").toString());// 存入集合
                            });
                }
            }
        } catch (Exception e) {

        }

        return videoLinkList;
    }

    // 用于 List<Map<String, Object>> 排序
    public static Integer getIndexValueInMap(Map<String, Object> map) {
        return (Integer) map.get("index");
    }
}
